﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;       // 地图图层相关接口（ILayer/ILegendClass）
using ESRI.ArcGIS.Display;     // 符号与显示相关接口（ISymbol/IColor）
using ESRI.ArcGIS.esriSystem;  // ArcGIS系统基础接口（IPropertySet等）
using ESRI.ArcGIS.SystemUI;    // 系统UI相关接口
using ESRI.ArcGIS.Controls;    // 控件相关接口（SymbologyControl）
using ESRI.ArcGIS.Geodatabase; // 地理数据库相关接口（IFeatureClass）



namespace MyMap
{
    public partial class SymbolSelectDialog : Form
    {
        private ILegendClass m_legendClass;       // 当前选中的图例类（用于更新符号）
        private ILayer m_layer;                   // 当前操作的图层（判断点/线/面类型）
        private IStyleGalleryItem m_styleGalleryItem; // 当前选中的符号样式项
        private ISymbol m_symbol;                 // 当前选中的符号对象
        private Image m_symbolImage;              // 符号预览图像

        public ISymbol currentSymbol()
        {
            return m_symbol;
        }


        public SymbolSelectDialog(ILegendClass tempLegendClass, ILayer tempLayer)
        {
            InitializeComponent(); // 初始化窗体控件
                                   // 赋值成员变量
            m_legendClass = tempLegendClass;
            m_layer = tempLayer;
            // 配置符号文件选择器（筛选*.ServerStyle文件）
            openFileDialog1.Filter = "ServerStyle符号文件 (*.ServerStyle)|*.ServerStyle|所有文件 (*.*)|*.*";
            openFileDialog1.Title = "选择自定义符号文件";
        }

        private void setFeatureClassStyle(esriSymbologyStyleClass tempSymbologyStyleClass)
        {
            this.axSymbologyControl.StyleClass = tempSymbologyStyleClass;
            ISymbologyStyleClass symbologyStyleClass = this.axSymbologyControl.GetStyleClass(tempSymbologyStyleClass);
            if (this.m_legendClass != null)
            {
                IStyleGalleryItem currentStyleGalleryItem = new ServerStyleGalleryItem();
                currentStyleGalleryItem.Name = "当前符号";
                currentStyleGalleryItem.Item = m_legendClass.Symbol;
                symbologyStyleClass.AddItem(currentStyleGalleryItem, 0);
                m_styleGalleryItem = currentStyleGalleryItem;
            }
            symbologyStyleClass.SelectItem(0);
        }


        // 根据图层类型为SymbolControl导入相应的符号样式文件，如点、线、面，并设置控件的可视性
        private void SymbolSelectDialog_Load(object sender, EventArgs e)
        {
            // 取得ArcGIS安装路径
            string sInstall = ESRI.ArcGIS.RuntimeManager.ActiveRuntime.Path;

            // 载入ESRI.ServerStyle文件到SymbologyControl
            this.axSymbologyControl.LoadStyleFile(sInstall + "Styles\\ESRI.ServerStyle");

            // 确定图层的类型（点、线、面），设置SymbologyControl的StyleClass，设置控件的可见性
            IGeoFeatureLayer geoFeatureLayer = m_layer as IGeoFeatureLayer;
            switch ((m_layer as IFeatureLayer).FeatureClass.ShapeType)
            {
                case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint:
                    this.setFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassMarkerSymbols);
                    this.numericUpDownAngle.Enabled = true;
                    this.labelAngle.Enabled = true;
                    this.numericUpDownSize.Enabled = true;
                    this.labelSize.Enabled = true;
                    this.numericUpDownWidth.Enabled = false;
                    this.labelWidth.Enabled = false;
                    this.buttonFrameColor.Enabled = false;
                    this.labelFrameColor.Enabled = false;
                    break;
                case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline:
                    this.setFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassLineSymbols);
                    this.numericUpDownAngle.Enabled = false;
                    this.labelAngle.Enabled = false;
                    this.numericUpDownSize.Enabled = false;
                    this.labelSize.Enabled = false;
                    this.numericUpDownWidth.Enabled = true;
                    this.labelWidth.Enabled = true;
                    this.buttonFrameColor.Enabled = false;
                    this.labelFrameColor.Enabled = false;
                    break;
                case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon:
                case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryMultiPatch:
                    this.setFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassFillSymbols);
                    this.numericUpDownAngle.Enabled = false;
                    this.labelAngle.Enabled = false;
                    this.numericUpDownSize.Enabled = false;
                    this.labelSize.Enabled = false;
                    this.numericUpDownWidth.Enabled = true;
                    this.labelWidth.Enabled = true;
                    this.buttonFrameColor.Enabled = true;
                    this.labelFrameColor.Enabled = true;
                    break;
                default:
                    this.Close();
                    break;
            }
        }

        private void ButtonOk_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;

            // 取得选定的符号
            m_symbol = m_styleGalleryItem.Item as ISymbol;
            // 更新预览图像
            m_symbolImage = this.pictureBoxPreview.Image;
            // 关闭窗体
            this.Close();
        }

        private void ButtonCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        private void AxSymbologyControl_OnMouseDown(object sender, ISymbologyControlEvents_OnMouseDownEvent e)
        {
            this.buttonOk.PerformClick();
        }

        private void previewImage()
        {
            stdole.IPictureDisp picture = this.axSymbologyControl.GetStyleClass(
                this.axSymbologyControl.StyleClass
            ).PreviewItem(m_styleGalleryItem, this.pictureBoxPreview.Width, this.pictureBoxPreview.Height);
            System.Drawing.Image image = System.Drawing.Image.FromHbitmap(new System.IntPtr(picture.Handle));
            this.pictureBoxPreview.Image = image;
        }

        private void axSymbologyControl_OnStyleClassChanged(object sender, ISymbologyControlEvents_OnStyleClassChangedEvent e)
        {
            switch (((ISymbologyStyleClass)e.symbologyStyleClass).StyleClass)
            {
                case esriSymbologyStyleClass.esriStyleClassMarkerSymbols:
                    this.numericUpDownAngle.Enabled = true;
                    this.labelAngle.Enabled = true;
                    this.numericUpDownSize.Enabled = true;
                    this.labelSize.Enabled = true;
                    this.numericUpDownWidth.Enabled = false;
                    this.labelWidth.Enabled = false;
                    this.buttonFrameColor.Enabled = false;
                    this.labelFrameColor.Enabled = false;
                    break;
                case esriSymbologyStyleClass.esriStyleClassLineSymbols:
                    this.setFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassLineSymbols);
                    this.numericUpDownAngle.Enabled = false;
                    this.labelAngle.Enabled = false;
                    this.numericUpDownSize.Enabled = false;
                    this.labelSize.Enabled = false;
                    this.numericUpDownWidth.Enabled = true;
                    this.labelWidth.Enabled = true;
                    this.buttonFrameColor.Enabled = false;
                    this.labelFrameColor.Enabled = false;
                    break;
                case esriSymbologyStyleClass.esriStyleClassFillSymbols:
                    this.setFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassFillSymbols);
                    this.numericUpDownAngle.Enabled = false;
                    this.labelAngle.Enabled = false;
                    this.numericUpDownSize.Enabled = false;
                    this.labelSize.Enabled = false;
                    this.numericUpDownWidth.Enabled = true;
                    this.labelWidth.Enabled = true;
                    this.buttonFrameColor.Enabled = true;
                    this.labelFrameColor.Enabled = true;
                    break;

            }
        }

        // 颜色转换函数：IRgbColor to System.Drawing.Color
        private Color convertIRgbColorToColor(IRgbColor rgbColor)
        {
            return ColorTranslator.FromOle(rgbColor.RGB);
        }

        // 颜色转换函数：System.Drawing.Color to IRgbColor
        private IColor convertColorToIColor(Color color)
        {
            IColor pColor = new RgbColorClass();
            pColor.RGB = color.B * 65536 + color.G * 256 + color.R;
            return pColor;
        }

        private void axSymbologyControl_OnItemSelected(object sender, ISymbologyControlEvents_OnItemSelectedEvent e)
        {
            m_styleGalleryItem = e.styleGalleryItem as IStyleGalleryItem;

            // 将所选符号的样式参数设置在相应控件中
            Color color;
            switch (this.axSymbologyControl.StyleClass)
            {
                case esriSymbologyStyleClass.esriStyleClassMarkerSymbols: // 点符号
                    color = this.convertIRgbColorToColor(
                        ((IMarkerSymbol)m_styleGalleryItem.Item).Color as IRgbColor
                    );
                    // 设置点符号的角度和大小初始值
                    this.numericUpDownAngle.Value = (decimal)((IMarkerSymbol)this.m_styleGalleryItem.Item).Angle;
                    this.numericUpDownSize.Value = (decimal)((IMarkerSymbol)this.m_styleGalleryItem.Item).Size;
                    break;
                case esriSymbologyStyleClass.esriStyleClassLineSymbols: // 线符号
                    color = this.convertIRgbColorToColor(
                        ((ILineSymbol)m_styleGalleryItem.Item).Color as IRgbColor
                    );
                    // 设置线宽初始值
                    this.numericUpDownWidth.Value = (decimal)((ILineSymbol)this.m_styleGalleryItem.Item).Width;
                    break;
                case esriSymbologyStyleClass.esriStyleClassFillSymbols: // 面符号
                    color = this.convertIRgbColorToColor(
                        ((IFillSymbol)m_styleGalleryItem.Item).Color as IRgbColor
                    );
                    // 设置外边线颜色和宽度
                    this.buttonFrameColor.BackColor = this.convertIRgbColorToColor(
                        ((IFillSymbol)m_styleGalleryItem.Item).Outline.Color as IRgbColor
                    );
                    this.numericUpDownWidth.Value = (decimal)((IFillSymbol)this.m_styleGalleryItem.Item).Outline.Width;
                    break;
                default:
                    color = Color.Black;
                    break;
            }
            // 设置按钮背景色
            this.buttonColor.BackColor = color;
            // 预览符号
            previewImage();
        }

        // 调整点符号大小
        private void NumericUpDownSize_ValueChanged(object sender, EventArgs e)
        {
            ((IMarkerSymbol)this.m_styleGalleryItem.Item).Size = (double)this.numericUpDownSize.Value;
            this.previewImage();
        }

        private void NumericUpDownWidth_ValueChanged(object sender, EventArgs e)
        {
            switch (this.axSymbologyControl.StyleClass)
            {
                case esriSymbologyStyleClass.esriStyleClassLineSymbols:
                    ((ILineSymbol)this.m_styleGalleryItem.Item).Width = Convert.ToDouble(this.numericUpDownWidth.Value);
                    break;
                case esriSymbologyStyleClass.esriStyleClassFillSymbols:
                    ILineSymbol lineSymbol = ((IFillSymbol)this.m_styleGalleryItem.Item).Outline;
                    lineSymbol.Width = Convert.ToDouble(this.numericUpDownWidth.Value);
                    ((IFillSymbol)this.m_styleGalleryItem.Item).Outline = lineSymbol;
                    break;
            }
            this.previewImage();
        }

        private void NumericUpDownAngle_ValueChanged(object sender, EventArgs e)
        {
            ((IMarkerSymbol)this.m_styleGalleryItem.Item).Angle = (double)this.numericUpDownAngle.Value;
            this.previewImage();
        }

        private void ButtonColor_Click(object sender, EventArgs e)
        {
            ColorDialog colorDialog = new ColorDialog();
            if (colorDialog.ShowDialog() == DialogResult.OK)
            {

                // 将颜色按钮的背景色设置为用户选定的颜色
                this.buttonColor.BackColor = colorDialog.Color;
                // 设置符号颜色为用户选定的颜色
                switch (this.axSymbologyControl.StyleClass)
                {
                    case esriSymbologyStyleClass.esriStyleClassMarkerSymbols:
                        ((IMarkerSymbol)this.m_styleGalleryItem.Item).Color = this.convertColorToIColor(colorDialog.Color);
                        break;
                    case esriSymbologyStyleClass.esriStyleClassLineSymbols:
                        ((ILineSymbol)this.m_styleGalleryItem.Item).Color = this.convertColorToIColor(colorDialog.Color);
                        break;
                    case esriSymbologyStyleClass.esriStyleClassFillSymbols:
                        ((IFillSymbol)this.m_styleGalleryItem.Item).Color = this.convertColorToIColor(colorDialog.Color);
                        break;
                }
            }
            this.previewImage();
        }

        private void ButtonFrameColor_Click(object sender, EventArgs e)
        {
            ColorDialog colorDialog = new ColorDialog();
            if (colorDialog.ShowDialog() == DialogResult.OK)
            {
                // 取得面符号中的外框线符号
                ILineSymbol lineSymbol = ((IFillSymbol)this.m_styleGalleryItem.Item).Outline;
                // 设置外框线颜色
                lineSymbol.Color = this.convertColorToIColor(colorDialog.Color);
                // 重新设置面符号中的外框线符号
                ((IFillSymbol)this.m_styleGalleryItem.Item).Outline = lineSymbol;
                // 设置按钮背景颜色
                this.buttonFrameColor.BackColor = colorDialog.Color;
                this.previewImage();
            }
        }

        private bool m_bContextMenuMoreSymbolInitiated = false;

        private void contextMenuStripMoreSymbol_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            ToolStripMenuItem toolStripMenuItem = (ToolStripMenuItem)e.ClickedItem;

            // 如果单击的是“添加符号”
            if (toolStripMenuItem.Name == "AddMoreSymbol")
            {
                // 弹出打开文件对话框
                OpenFileDialog openFileDialog = new OpenFileDialog();
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    // 导入stylefile到symbolControl
                    this.axSymbologyControl.LoadStyleFile(openFileDialog.FileName);
                    // 刷新axSymbologyControl控件
                    this.axSymbologyControl.Refresh();
                }
            }
            else
            {
                if (!toolStripMenuItem.Checked)
                {
                    this.axSymbologyControl.LoadStyleFile(toolStripMenuItem.Name);
                    this.axSymbologyControl.Refresh();
                }
                else
                {
                    this.axSymbologyControl.RemoveFile(toolStripMenuItem.Name);
                    this.axSymbologyControl.Refresh();
                }
            }
        }

        private void ButtonMoreSymbols_Click(object sender, EventArgs e)
        {
            if (!m_bContextMenuMoreSymbolInitiated)
            {
                // 取得ArcGIS安装路径
                string sInstall = ESRI.ArcGIS.RuntimeManager.ActiveRuntime.Path;

                string sPath = System.IO.Path.Combine(sInstall, "Styles");
                // 取得菜单项数量
                string[] styleNames = System.IO.Directory.GetFiles(sPath, "*.ServerStyle");
                ToolStripMenuItem[] symbolContextMenuItem = new ToolStripMenuItem[styleNames.Length + 1];
                // 循环添加其它符号菜单项到菜单
                for (int i = 0; i < styleNames.Length; i++)
                {
                    symbolContextMenuItem[i] = new ToolStripMenuItem();
                    symbolContextMenuItem[i].CheckOnClick = true;
                    symbolContextMenuItem[i].Text = System.IO.Path.GetFileNameWithoutExtension(styleNames[i]);
                    if (symbolContextMenuItem[i].Text == "ESRI")
                    {
                        symbolContextMenuItem[i].Checked = true;
                    }
                    symbolContextMenuItem[i].Name = styleNames[i];
                }

                // 添加“更多符号”菜单项到菜单最后一项
                symbolContextMenuItem[styleNames.Length] = new ToolStripMenuItem();
                symbolContextMenuItem[styleNames.Length].Text = "添加符号";
                symbolContextMenuItem[styleNames.Length].Name = "AddMoreSymbol";

                // 添加所有的菜单项到菜单
                this.contextMenuStripMoreSymbol.Items.AddRange(symbolContextMenuItem);
                this.m_bContextMenuMoreSymbolInitiated = true;
            }
            // 显示菜单
            this.contextMenuStripMoreSymbol.Show(this.buttonMoreSymbols.Location);
        }

       
        
    }
}
